package org.xserver.common.util;

import java.io.IOException;

import org.xserver.component.json.JsonManager;
import org.xserver.component.json.bean.JQueryTab;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * JsonEngine define two kind of {@link ObjectMapper} instances. The
 * {@link JsonEngine#DEFAULT_JACKSON_MAPPER} is default serialize or deserialize
 * mapper. The {@link JsonEngine#FILTER_JACKSON_MAPPER} based on the first
 * mapper include filter feature.
 * 
 * <h3>Note</h3> if the bean annotation with {@code annotation}
 * {@link JsonFilter} serialization will use
 * {@link JsonEngine#FILTER_JACKSON_MAPPER} the annotation's value must be
 * {@link JsonManager#JSON_FILTER_EXCEPT_FIELD}, else will use default mapper
 * {@link JsonEngine#DEFAULT_JACKSON_MAPPER} to serialize bean.
 * 
 * 
 * @author idoldefine
 * @since 2013/02/01
 * 
 */
public class JsonEngine {
	public static final ObjectMapper DEFAULT_JACKSON_MAPPER;
	public static final ObjectMapper FILTER_JACKSON_MAPPER;

	public static final boolean JACKSON_ENABLE = ReflectionUtil
			.classFound(new String[] { ObjectMapper.class.getName(),
					JsonGenerator.class.getName() });

	static {
		if (JACKSON_ENABLE) {
			JsonFactory jf = new JsonFactory();
			jf.enable(Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);
			jf.enable(Feature.ALLOW_COMMENTS);
			jf.enable(Feature.ALLOW_NON_NUMERIC_NUMBERS);
			jf.enable(Feature.ALLOW_SINGLE_QUOTES);
			jf.enable(Feature.ALLOW_UNQUOTED_CONTROL_CHARS);
			jf.enable(Feature.ALLOW_UNQUOTED_FIELD_NAMES);

			DEFAULT_JACKSON_MAPPER = new ObjectMapper(jf);
			DEFAULT_JACKSON_MAPPER.setSerializationInclusion(Include.NON_NULL);
			DEFAULT_JACKSON_MAPPER.configure(
					SerializationFeature.WRITE_NULL_MAP_VALUES, false);
			DEFAULT_JACKSON_MAPPER
					.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
			DEFAULT_JACKSON_MAPPER.configure(
					SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

			FILTER_JACKSON_MAPPER = new ObjectMapper(jf);
			FILTER_JACKSON_MAPPER.setSerializationInclusion(Include.NON_NULL);
			FILTER_JACKSON_MAPPER.configure(
					SerializationFeature.WRITE_NULL_MAP_VALUES, false);
			FILTER_JACKSON_MAPPER
					.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
			FILTER_JACKSON_MAPPER.configure(
					SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		} else {
			DEFAULT_JACKSON_MAPPER = null;
			FILTER_JACKSON_MAPPER = null;
		}
	}

	public static void main(String[] args) throws JsonParseException,
			JsonMappingException, IOException {
		JQueryTab jt2 = new JQueryTab();

		jt2.setContent("sdads");
		System.out.println(JsonManager.json(jt2));
	}
}
